package com.component.encrypt;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

/**
 * 加密工具类
 * 
 * @author AllenWu
 */
public class EncryptUtil {
	/**
	 * 生成指定位数密钥对
	 * 
	 * @param n
	 *            密钥长度
	 * @return 密钥对(公钥/密钥)
	 * @throws Exception
	 */
	public static Map<String, String> getKeyPair(int n) throws Exception {
		return RSA.generateKeyPair(n);
	}

	/**
	 * 生成1024位数密钥对
	 * 
	 * @return 密钥对(公钥/密钥)
	 * @throws Exception
	 */
	public static Map<String, String> getKeyPair() throws Exception {
		return getKeyPair(0);
	}

	/**
	 * 生成RSA签名
	 * 
	 * @param json
	 *            需要签名的数据
	 * @param privateKey
	 *            密钥
	 * @return 签名密文
	 * @throws UnsupportedEncodingException
	 */
	@SuppressWarnings("unchecked")
	public static String handleSign(JSONObject json, String privateKey) throws Exception {
		Iterator<Entry<String, Object>> iter = json.entrySet().iterator();
		StringBuffer sbuffer = new StringBuffer();
		String sign = "";
		while (iter.hasNext()) {
			Entry<String, Object> entry = iter.next();
			sbuffer.append(entry.getValue());
		}

		if (StringUtils.isNotEmpty(privateKey)) {
			byte[] data = RSA.sign(sbuffer.toString().getBytes(), Base64.decode2(privateKey));
			sign = new String(Base64.encodeBase64(data));
		}

		return sign;
	}

	/**
	 * RSA加密
	 * 
	 * @param source
	 *            需要加密的数据
	 * @param publicKey
	 *            公钥
	 * @return 密文
	 * @throws Exception
	 */
	public static String encryptRSA(String source, String publicKey) throws Exception {
		byte[] data = RSA.encrypt(source.getBytes(), publicKey.getBytes(), Config.TRANSFORMATION_RSA);
		return new String(Base64.encodeBase64(data));
	}

	/**
	 * AES加密
	 * 
	 * @param source
	 *            需要加密的数据
	 * @param key
	 *            随机加密密钥
	 * @return 密文
	 * @throws UnsupportedEncodingException
	 */
	public static String encryptAES(String source, String key) throws Exception {
		byte[] data = AES.encrypt(source.getBytes(), key.getBytes());
		return new String(Base64.encodeBase64(data));
	}

	/**
	 * 对表单数据进行签名并加密
	 * 
	 * @param jsonData
	 * @return JSONObject
	 * @throws Exception
	 */
	public static JSONObject encryptData(JSONObject jsonData) throws Exception {

		JSONObject paramJson = new JSONObject();
		// No.1 生成签名 服务器的私钥
		jsonData.put("sign", handleSign(jsonData, Config.PRIVATEKEY));
		// No.2 随机生成16位加密密码
		String merchantAesKey = RandomUtil.getRandom(16);
		// No.3 数据加密
		paramJson.put("encryptData", encryptAES(jsonData.toString(), merchantAesKey));
		// No.4 加密密码加密 自己的公钥
		paramJson.put("encryptKey", encryptRSA(merchantAesKey, Config.PUBLICKEY));
		paramJson.put("partner", Config.partner);
		return paramJson;
	}
}
